package com.niiwoo.civet.trade.service.local.contract;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.constant.PlateformConstant;
import com.niiwoo.civet.account.dto.response.AccountCompanyDTO;
import com.niiwoo.civet.account.service.AccountCompanyDubboService;
import com.niiwoo.civet.trade.constant.AmountHandleConstant;
import com.niiwoo.civet.trade.dao.entity.FadadaContractTemplateFile;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectContract;
import com.niiwoo.civet.trade.dto.request.loan.RepaymentPlanDTO;
import com.niiwoo.civet.trade.enums.PeriodUnitEnum;
import com.niiwoo.civet.trade.enums.RepaymentTypeEnum;
import com.niiwoo.civet.trade.service.local.contract.vo.InvestorContractDTO;
import com.niiwoo.civet.trade.service.local.plan.BorrowerInvestorRepaymentContext;
import com.niiwoo.civet.trade.utils.SysNumberUtil;
import com.niiwoo.civet.user.dto.request.SimpleOrgInfo;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.civet.user.service.UserAuthorizationInfoDubboService;
import com.niiwoo.civet.user.service.UserIdentityDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO.DynamicTable;
import com.niiwoo.tripod.fadada.dto.response.FadadaResponseDTO;
import com.niiwoo.tripod.fadada.enums.SignClientRoleEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.*;

/**
 * 俊拓-企业居间借款合同
 *
 * @author liaojunjun
 */
@Service
public class JunTuoCompanyFastLoanContract extends AbstractFadadaContract {

    private static final Logger logger = LoggerFactory.getLogger(JunTuoCompanyFastLoanContract.class);

    @Reference(version = "1.0.0")
    private UserIdentityDubboService userIdentityDubboService;
    @Reference(version = "1.0.0")
    private UserAuthorizationInfoDubboService userAuthorizationInfoDubboService;
    @Reference(version = "1.0.0")
    private OrganizationDubboService organizationDubboService;
    @Reference(version = "1.0.0")
    private AccountCompanyDubboService accountCompanyDubboService;

    @Autowired
    private PrivacyMasks privacyMasks;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private ContractBaseService contractBaseService;
    @Autowired
    private BorrowerInvestorRepaymentContext borrowerInvestorRepaymentContext;

    @Value("${platform.caCertId}")
    private String platformCaCertId;

    @Override
    public ProjectContract contractHandler(FadadaContractTemplateFile contractTemplate, String bizContractNo,
                                           Project project, String userId) throws Exception {
        logger.info("俊拓-企业借款合同处理开始... projectId:{}", project.getProjectId());
        String contractId = snowflakeIdWorker.nextId() + "";
        SimpleOrgInfo borrowOrg = organizationDubboService.getByOrgId(project.getBorrowUserId());
        SimpleOrgInfo guarantee = organizationDubboService.getByOrgId(project.getGuaranteeCompanyOrgId());
        if (guarantee == null) {
            logger.error("俊拓-企业借款合同处理异常 guarantee is null. projectId:{},orgId:{}, project.getGuaranteeCompanyOrgId:{}", project.getProjectId(), project.getOrgId(), JSON.toJSON(project.getGuaranteeCompanyOrgId()));
            throw new BizException("TRD10005", "俊拓-企业借款合同处理异常 guarantee is null");
        }
        AccountCompanyDTO accountCompanyByBusinessLicense = accountCompanyDubboService.getAccountCompanyByBusinessLicense(project.getConsultingBusinessLicense());
        if (accountCompanyByBusinessLicense == null) {
            logger.error("俊拓-企业借款合同处理异常 informationConsultantOrg is null. projectId:{}, consultingBusinessLicense:{}", project.getProjectId(), project.getConsultingBusinessLicense());
            throw new BizException("TRD10005", "俊拓-企业借款合同处理异常 informationConsultantOrg is null");
        }
        SimpleOrgInfo informationConsultantOrg = organizationDubboService.getByOrgId(accountCompanyByBusinessLicense.getUserId());
        if (informationConsultantOrg == null) {
            logger.error("俊拓-企业借款合同处理异常 informationConsultantOrg is null. projectId:{}, AccountCompanyDTO:{}", project.getProjectId(), JSON.toJSON(accountCompanyByBusinessLicense));
            throw new BizException("TRD10005", "俊拓-企业借款合同OrganizationDubboService处理异常 informationConsultantOrg is null");
        }

        this.generateContract(contractTemplate, contractId, bizContractNo, project, contractBaseService.getInvestUserInfo(project.getProjectId()), guarantee, borrowOrg, informationConsultantOrg);

        ProjectContract result = this.signContract(contractTemplate, contractId, project, contractBaseService.getInvestUserInfo(project.getProjectId()), guarantee, borrowOrg, informationConsultantOrg);

        this.contractFilling(contractId);
        logger.info("俊拓-企业借款合同处理结束... projectId:{}", project.getProjectId());
        return result;
    }

    private void generateContract(FadadaContractTemplateFile contractTemplate, String contractId, String bizContractNo,
                                  Project project, List<InvestorContractDTO> projectInvestOrderList, SimpleOrgInfo guarantee, SimpleOrgInfo borrowOrg, SimpleOrgInfo informationConsultantOrg) throws Exception {
        logger.info("俊拓-企业借款合同生成开始... projectId:{}", project.getProjectId());

        GenerateContractRequestDTO dto = new GenerateContractRequestDTO();
        dto.setContractId(contractId);
        dto.setDocTitle(contractTemplate.getTemplateName());
        dto.setTemplateId(contractTemplate.getTemplateId());

        Map<String, String> parameterMap = new HashMap<String, String>();
        parameterMap.put("contractNo", bizContractNo);
        parameterMap.put("repaymentTypeName", RepaymentTypeEnum.enumOf(project.getRepaymentType()).getDesc());
        parameterMap.put("borrowerName", "乙方（借款人）： ".concat(borrowOrg.getOrganizationName())); // 借款人
        parameterMap.put("borrowerIdCard", "统一社会信用代码/营业执照编号： ".concat(privacyMasks.maskInstitutionalReditCode(StringUtils.isBlank(borrowOrg.getUnifiedSocialCreditCode()) ? borrowOrg.getCharterCode() : borrowOrg.getUnifiedSocialCreditCode())));
        parameterMap.put("borrowEmail", "电子邮箱： " + borrowOrg.getEmail());
        parameterMap.put("borrowAgentRealName", "联系人： " + borrowOrg.getRepresentative());
        parameterMap.put("borrowAgentIdentityCard", "身份证号码： " + (StringUtils.isNoneBlank(borrowOrg.getLegalPersonCertNumber()) ? privacyMasks.maskIdCard(privacyMasks.decryptPrivacy(borrowOrg.getLegalPersonCertNumber())) : ""));
        parameterMap.put("borrowAgentPhoneNumber", "联系方式： " + (StringUtils.isNoneBlank(borrowOrg.getLegalPersonPhoneNumber()) ? privacyMasks.decryptPrivacy(borrowOrg.getLegalPersonPhoneNumber()) : ""));
        parameterMap.put("borrowerAddress", "地址： ".concat((StringUtils.isBlank(borrowOrg.getAddress())) ? project.getLoanProvince().concat(project.getLoanCity()).concat(project.getLoanArea()) : borrowOrg.getAddress()));
        parameterMap.put("borrowAmount", project.getContractAmount().setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString()); // 借款金额
        parameterMap.put("capitalAmount", SysNumberUtil.amountChineseFormat(project.getContractAmount().toString())); // 大写借款金额
        parameterMap.put("deadLine", project.getDeadline() + "");// 借款期限
        parameterMap.put("projectTitle", project.getTitle().replaceAll("借款用途：", "").replaceAll("借款用于", ""));
        parameterMap.put("companyGuarantee", guarantee.getOrganizationName());// 担保公司
        parameterMap.put("companyGuaranteeReditCode", privacyMasks.maskInstitutionalReditCode(StringUtils.isBlank(guarantee.getUnifiedSocialCreditCode()) ? guarantee.getCharterCode() : guarantee.getUnifiedSocialCreditCode()));// 担保公司机构信用代码
        parameterMap.put("companyGuaranteeEmail", guarantee.getEmail());
        parameterMap.put("informationConsultantName", informationConsultantOrg.getOrganizationName());// 咨询信息方
        parameterMap.put("informationConsultantReditCode", privacyMasks.maskInstitutionalReditCode(StringUtils.isBlank(informationConsultantOrg.getUnifiedSocialCreditCode()) ? informationConsultantOrg.getCharterCode() : informationConsultantOrg.getUnifiedSocialCreditCode()));// 咨询信息方信用代码
        parameterMap.put("informationConsultantAddress", informationConsultantOrg.getAddress());
        parameterMap.put("niiwooReditCode", privacyMasks.maskInstitutionalReditCode(PlateformConstant.NIIWOO_REDIT_CODE));

        parameterMap.put("dayInvestRate", project.getBorrowRate().multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .divide(new BigDecimal(AmountHandleConstant.YEAR_OF_DAY), MathContext.DECIMAL128)
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());// 借款日利率
        parameterMap.put("annualInvestRate", project.getBorrowRate().multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());// 借款年利率
        parameterMap.put("borrowPenaltyRate", project.getPenaltyRate().multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString()); // 借款逾期罚息日率

        Date lastRepaymentDate = PeriodUnitEnum.MONTH.getValue().equals(project.getDeadlineUnit())
                ? DateUtils.addDays(DateUtils.addMonths(project.getFullSuccessTime(), project.getDeadline()), -1)
                : DateUtils.addDays(project.getFullSuccessTime(), project.getDeadline());
        parameterMap.put("lastRepaymentYear", DateFormatUtils.format(lastRepaymentDate, "yyyy"));
        parameterMap.put("lastRepaymentMonth", DateFormatUtils.format(lastRepaymentDate, "MM"));
        parameterMap.put("lastRepaymentDay", DateFormatUtils.format(lastRepaymentDate, "dd"));


        // 平台管理费
        BigDecimal beforeManageFee = project.getBeforeManageFee() == null ? BigDecimal.ZERO : project.getBeforeManageFee();
        BigDecimal beforeManageRate = project.getBeforeManageRate() == null ? BigDecimal.ZERO : project.getBeforeManageRate();
        BigDecimal platformManageFeeTotal = project.getManageFee().add(beforeManageFee);
        parameterMap.put("platformManagerFee", platformManageFeeTotal.toString());
        parameterMap.put("capitalPlatformManagerFee", SysNumberUtil.amountChineseFormat(platformManageFeeTotal.toString()));
        parameterMap.put("platformManagerRateDay", project.getManageRate().add(beforeManageRate).multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .divide(BigDecimal.valueOf(project.getDeadline()), MathContext.DECIMAL128)
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());
        parameterMap.put("platformManagerRateYear", project.getManageRate().add(beforeManageRate).multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .divide(BigDecimal.valueOf(project.getDeadline()), MathContext.DECIMAL128).multiply(new BigDecimal(AmountHandleConstant.YEAR_OF_DAY))
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());

        // 担保服务费
        BigDecimal guaranteeServiceFeeTotal = project.getContractAmount().multiply(project.getGuaranteeRate())
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN);
        parameterMap.put("guaranteeServiceFee", guaranteeServiceFeeTotal.toString());
        parameterMap.put("capitalGuaranteeServiceFee", SysNumberUtil.amountChineseFormat(guaranteeServiceFeeTotal.toString()));
        parameterMap.put("guaranteeRateDay", project.getGuaranteeRate().multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .divide(BigDecimal.valueOf(project.getDeadline()), MathContext.DECIMAL128)
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());
        parameterMap.put("guaranteeRateYear", project.getGuaranteeRate().multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .divide(BigDecimal.valueOf(project.getDeadline()), MathContext.DECIMAL128).multiply(new BigDecimal(AmountHandleConstant.YEAR_OF_DAY))
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());

        // 咨询服务费
        BigDecimal consultantFee = project.getBeforeSeekAdviceServiceFee().add(project.getConsultingFee())
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN);
        parameterMap.put("totalConsultingFee", consultantFee.toString());
        parameterMap.put("capitalTotalConsultingFee", SysNumberUtil.amountChineseFormat(consultantFee.toString()));
        parameterMap.put("consultRateDay", project.getBeforeSeekAdviceServiceFeeRate().add(project.getConsultingRate()).multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .divide(BigDecimal.valueOf(project.getDeadline()), MathContext.DECIMAL128)
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());
        parameterMap.put("consultRateYear", project.getBeforeSeekAdviceServiceFeeRate().add(project.getConsultingRate()).multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .divide(BigDecimal.valueOf(project.getDeadline()), MathContext.DECIMAL128).multiply(new BigDecimal(AmountHandleConstant.YEAR_OF_DAY))
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());

        List<RepaymentPlanDTO> repaymentPlanDTOList = borrowerInvestorRepaymentContext.getBorrowerRepaymentPlan(
                RepaymentTypeEnum.enumOf(project.getRepaymentType()), project.getContractAmount(), project.getBorrowRate(),
                project.getDeadline(), PeriodUnitEnum.enumOf(project.getDeadlineUnit()),
                project.getFullSuccessTime() == null ? new Date() : project.getFullSuccessTime(), project.getLeastCalculateInterestDays());

        BigDecimal interestTotal = BigDecimal.ZERO;
        for (RepaymentPlanDTO repaymentPlanDTO : repaymentPlanDTOList) {
            interestTotal = interestTotal.add(repaymentPlanDTO.getInterest());
        }

        BigDecimal payTotal = interestTotal.add(platformManageFeeTotal).add(guaranteeServiceFeeTotal).add(consultantFee);
        //借款人综合资金成本费率计算公式为：（利息 +平台管理费 +担保服务费） /借款金额 /借款期限 *12
        BigDecimal payTotalRateYear = payTotal.divide(project.getContractAmount(), MathContext.DECIMAL128)
                .divide(BigDecimal.valueOf(project.getDeadline()), MathContext.DECIMAL128)
                .multiply(new BigDecimal((PeriodUnitEnum.MONTH.getValue().equals(project.getDeadlineUnit()) ? AmountHandleConstant.YEAR_OF_MONTH : AmountHandleConstant.YEAR_OF_DAY)))
                .multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
                .setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN);

        parameterMap.put("payTotal", payTotal.toString());  // 总支出上限
        parameterMap.put("capitalPayTotal", SysNumberUtil.amountChineseFormat(payTotal.toString()));
        parameterMap.put("payTotalRateYear", payTotalRateYear.toString());
        parameterMap.put("beginYear", DateFormatUtils.format(project.getFullSuccessTime(), "yyyy"));
        parameterMap.put("beginMonth", DateFormatUtils.format(project.getFullSuccessTime(), "MM"));
        parameterMap.put("beginDay", DateFormatUtils.format(project.getFullSuccessTime(), "dd"));
        parameterMap.put("signDate", DateFormatUtils.format(new Date(), "yyyy年MM月dd日"));

        // 投资人姓名列表
        List<List<String>> invNameList = new ArrayList<>();
        // 投资详情列表
        List<List<String>> invInvestInfoList = new ArrayList<>();
        // 投资人签名
        List<List<String>> invSignatureNamesList = new ArrayList<>();

        int index = 1;

        for (InvestorContractDTO projectInvestOrder : projectInvestOrderList) {
            // 投资人姓名
            String invNameText = "                甲方" + contractBaseService.toChinese(index) + "(出借人)：" + projectInvestOrder.getInvestUserName() + "\n"
                    + "                身份证号/统一社会信用代码/营业执照编号：    " + privacyMasks.maskIdCardSixTwo(Byte.valueOf("1").equals(projectInvestOrder.getInvestorType()) ? privacyMasks.decryptPrivacy(projectInvestOrder.getInvestorIdCard()) : projectInvestOrder.getInvestorIdCard());
            List<String> invNameCells = new ArrayList<>();
            invNameCells.add(invNameText);
            invNameList.add(invNameCells);

            // 投资人投资信息信息
            String invInvestInfoText = "                甲方" + contractBaseService.toChinese(index) + ":" + "￥"
                    + projectInvestOrder.getInvestAmount() + "元  大写："
                    + SysNumberUtil.amountChineseFormat(projectInvestOrder.getInvestAmount().toString());
            List<String> invInvestInfoCells = new ArrayList<>();
            invInvestInfoCells.add(invInvestInfoText);
            invInvestInfoList.add(invInvestInfoCells);

            // 签章信息
            String invSignatureNamesText = "                甲方" + contractBaseService.toChinese(index) + "（签章）：" + projectInvestOrder.getInvestUserName()
                    + "," + privacyMasks.maskIdCardSixTwo(Byte.valueOf("1").equals(projectInvestOrder.getInvestorType()) ? privacyMasks.decryptPrivacy(projectInvestOrder.getInvestorIdCard()) : projectInvestOrder.getInvestorIdCard());

            List<String> invSignatureNamesCells = new ArrayList<>();
            invSignatureNamesCells.add(invSignatureNamesText);
            invSignatureNamesList.add(invSignatureNamesCells);
            index++;
        }

        // 签章信息
        String borrowerSignatureNamesText = "                乙方（签章）：" + borrowOrg.getOrganizationName() + ","
                + privacyMasks.maskInstitutionalReditCode(StringUtils.isBlank(borrowOrg.getUnifiedSocialCreditCode()) ? borrowOrg.getCharterCode() : borrowOrg.getUnifiedSocialCreditCode());
        List<String> borrowerSignatureNamesCells = new ArrayList<>();
        borrowerSignatureNamesCells.add(borrowerSignatureNamesText);
        invSignatureNamesList.add(borrowerSignatureNamesCells);

        // 签章信息
        String companySignatureNamesText = "                丙方（签章）：" + guarantee.getOrganizationName();
        List<String> companySignatureNamesCells = new ArrayList<>();
        companySignatureNamesCells.add(companySignatureNamesText);
        invSignatureNamesList.add(companySignatureNamesCells);

        // 签章信息
        String platformSignatureNamesText = "                丁方（签章）：深圳市你我金融信息服务有限公司";
        List<String> platformSignatureNamesCells = new ArrayList<>();
        platformSignatureNamesCells.add(platformSignatureNamesText);
        invSignatureNamesList.add(platformSignatureNamesCells);

        // 签章信息
        String informationConsultantSignatureNamesText = "                戊方（签章）：" + informationConsultantOrg.getOrganizationName();
        List<String> informationConsultantSignatureNamesCells = new ArrayList<>();
        informationConsultantSignatureNamesCells.add(informationConsultantSignatureNamesText);
        invSignatureNamesList.add(informationConsultantSignatureNamesCells);

        // 投资人姓名列表
        // 表格header
        List<String> headers = new ArrayList<>();
        headers.add("");

        DynamicTable investNameTable = new DynamicTable();
        investNameTable.setInsertWay(1);
        investNameTable.setKeyword("合同编号");
        investNameTable.setCellHeight(30f);
        investNameTable.setHeaders(headers);
        investNameTable.setBorderFlag(false);
        investNameTable.setDatas(invNameList);

        DynamicTable investInfoTable = new DynamicTable();
        // investInfoTable.put("pageBegin",5);
        investInfoTable.setInsertWay(1);
        investInfoTable.setKeyword("各主体具体出借金额如下");
        investInfoTable.setCellHeight(30f);
        investInfoTable.setHeaders(headers);
        investInfoTable.setBorderFlag(false);
        investInfoTable.setDatas(invInvestInfoList);

        DynamicTable signNameTable = new DynamicTable();
        signNameTable.setInsertWay(1);
        signNameTable.setKeyword("该一定期限由你我金融制定。");
        signNameTable.setCellHeight(60f);
        signNameTable.setHeaders(headers);
        signNameTable.setCellVerticalAlignment(5);
        signNameTable.setDatas(invSignatureNamesList);
        signNameTable.setBorderFlag(false);

        List<DynamicTable> tables = new ArrayList<DynamicTable>();
        tables.add(investNameTable);
        tables.add(investInfoTable);
        tables.add(signNameTable);

        dto.setDynamicTables(tables);
        dto.setParameterMap(parameterMap);

        generateContract(dto);
        logger.info("俊拓-企业借款合同生成结束... projectId:{}", project.getProjectId());
    }

    private ProjectContract signContract(FadadaContractTemplateFile contractTemplate, String contractId,
                                         Project project, List<InvestorContractDTO> projectInvestOrderList, SimpleOrgInfo guarantee, SimpleOrgInfo borrowOrg, SimpleOrgInfo informationConsultantOrg) throws Exception {
        String METHOD_NAME = "法大大合同自动签署-满标借款合同 projectId:" + project.getProjectId();
        logger.info(METHOD_NAME);

        String transactionId = null;
        FadadaResponseDTO fadadaResponse = null;
        String docTitle = project.getBorrowUserName() + "的借款合同_" + contractId;
        logger.info("法大大合同自动签署-满标借款合同 投资人签署开始... projectId:{}", project.getProjectId());

        // 投资人签署
        int index = 1;
        for (InvestorContractDTO projectInvestOrder : projectInvestOrderList) {
            transactionId = snowflakeIdWorker.nextId() + "";
            String investorCaCertId = projectInvestOrder.getFadadaCacertId();
            String investorSignKeyword = "甲方" + contractBaseService.toChinese(index) + "（签章）："
                    + projectInvestOrder.getInvestUserName();
            fadadaResponse = extSignAuto(transactionId, contractId, investorCaCertId,
                    SignClientRoleEnum.INVESTOR.getValue(), docTitle, investorSignKeyword);
            index++;
        }
        logger.info("法大大合同自动签署-满标借款合同 投资人签署结束... projectId:{}", project.getProjectId());

        // 担保公司签署
        transactionId = snowflakeIdWorker.nextId() + "";
        String guaranteeCaCertId = guarantee.getFadadaCacertId();
        String guaranteeSignKeyword = "丙方（签章）：" + guarantee.getOrganizationName();
        fadadaResponse = extSignAuto(transactionId, contractId, guaranteeCaCertId,
                SignClientRoleEnum.GUARANTEE.getValue(), docTitle, guaranteeSignKeyword);
        logger.info("法大大合同自动签署-满标借款合同担保公司签署结束... projectId:{}", project.getProjectId());

        // 借款人签署
        transactionId = snowflakeIdWorker.nextId() + "";
        String borrowerCaCertId = borrowOrg.getFadadaCacertId();
        String borrowerSignKeyword = "乙方（签章）：" + borrowOrg.getOrganizationName();
        fadadaResponse = extSignAuto(transactionId, contractId, borrowerCaCertId,
                SignClientRoleEnum.BORROWER.getValue(), docTitle, borrowerSignKeyword);
        logger.info("法大大合同自动签署-满标借款合同 借款人签署结束... projectId:{}", project.getProjectId());

        // 平台公章
        transactionId = snowflakeIdWorker.nextId() + "";
        String platformSignKeyword = "丁方（签章）：深圳市你我金融信息服务有限公司";
        fadadaResponse = extSignAuto(transactionId, contractId, platformCaCertId,
                SignClientRoleEnum.PLATFORM.getValue(), docTitle, platformSignKeyword);
        logger.info("法大大合同自动签署-满标借款合同 平台签署结束... projectId:{}", project.getProjectId());

        // 咨询方签章
        transactionId = snowflakeIdWorker.nextId() + "";
        String informationConsultantCaCertId = informationConsultantOrg.getFadadaCacertId();
        String informationConsultantSignatureNamesText = "戊方（签章）：" + informationConsultantOrg.getOrganizationName();
        fadadaResponse = extSignAuto(transactionId, contractId, informationConsultantCaCertId,
                SignClientRoleEnum.GUARANTEE.getValue(), docTitle, informationConsultantSignatureNamesText);
        logger.info("法大大合同自动签署-满标借款合同 咨询方签署结束... projectId:{}", project.getProjectId());

        return this.buildContractUpdateRecord(contractTemplate.getTemplateId(), contractId, transactionId,
                fadadaResponse.getViewUrl(), fadadaResponse.getDownloadUrl());
    }

}
